package com.anysoft.utils;

import android.util.Base64;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;


public class RSACryptographyUtil {
    public static String RSA_PUBLIC_KEY = "";
    public static String RSA_PRIVATE_KEY = "";
    private static final String ALGORITHM_RSA = "RSA";
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    static {
        Map<String, Object> keyMap = null;//初始化密钥
        try {
            keyMap = initKey();
        } catch (Exception e) {
            e.printStackTrace();
        }
        RSA_PUBLIC_KEY = getPublicKey(keyMap);//公钥
        RSA_PRIVATE_KEY = getPrivateKey(keyMap);//私钥
    }

    /**
     * 解密
     * 用私钥解密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String data, String key)  {
        try {
            byte[] keyBytes = Base64.decode(key, Base64.DEFAULT);//对私钥解密
            /*取得私钥*/
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            /*对数据解密*/
//			Cipher cipher = Cipher.getInstance(TRANSFORMATION, new BouncyCastleProvider());//相同的原文、公钥能生成相同的密文。
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//相同的原文、公钥生成的密文不同
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] bs = Base64.decode(data, Base64.DEFAULT);
            byte[] doFinal = cipher.doFinal(bs);
            return new String(doFinal);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 加密
     * 用公钥加密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String data, String key)  {
        try {
            byte[] decode = Base64.decode(key, Base64.NO_WRAP);//对公钥解密
            /*取得公钥*/
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decode);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
            Key publicKey = keyFactory.generatePublic(x509KeySpec);
			/*对数据加密*/
            //如果使用Cipher cipher = Cipher.getInstance(TRANSFORMATION, new BouncyCastleProvider());//相同的原文、公钥能生成相同的密文。
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//相同的原文、公钥生成的密文不同
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] doFinal = cipher.doFinal(data.getBytes());
            String encryptString = Base64.encodeToString(doFinal, Base64.NO_WRAP);
            return encryptString;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 取得私钥
     *
     * @param keyMap
     * @return
     */
    public static String getPrivateKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return Base64.encodeToString(key.getEncoded(), Base64.NO_WRAP);
    }

    /**
     * 取得公钥
     *
     * @param keyMap
     * @return
     */
    public static String getPublicKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return Base64.encodeToString(key.getEncoded(), Base64.NO_WRAP);
    }

    /**
     * 初始化公钥和私钥
     *
     * @return
     * @throws Exception
     */
    public static Map<String, Object> initKey() throws Exception {
        KeyPairGenerator keyPairGen = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
        } catch (Exception e) {

        }
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//私钥
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

}
